package polymorphic;

/**
 * @author : niu niu
 * @version : 1.0.0
 * @date : 2022/9/13 21:50
 * 多态：同样的方法，在使用 不同的对象调用时，表现出不同的行为   本质：继承+重写
 *      同一个方法的多种状态
 *       同样的一件事情（行为/方法），发生在不同的对象上 ，表现出不同的结果
 *
 *       多态的实现：继承+方法重写
 *           一、★ 向上转型  >>>>>父类名称 父类引用 = new 子类实例； 从右向左，子类 is a 父类
 *                      不看父类，看 new 在那，若子类重写了方法  ，一定调用重写后的方法
 *                 发生情况：
 *                    1.直接赋值
 *                          父类名称 父类引用 = new 子类实例
 *                    2.方法的传参
 *                           public static void fun(Animal animal)
 *                    3.方法的返回值
 *                           public static Animal buyAnimal(String animalName)
 *                           return new Dog("66",2);
 *                  优点：参数统一化，方便进行子类的扩展
 *                         参数统一化：只要在方法的形参规定父类的引用，所有该类的子类对象都能使用父类引用来接受
 *                         方便进行子类的扩展：在进行子类扩展的时候，不需要做过多的处理，见Sharps的子类扩展
 *
 *                   能不能"."访问方法或者属性要看"前面"父类中有没有
 *  *                至于"."之后到底掉哦用的是父类方法 还是子类方法，要看"后面"new子类是否重写该方法
 *            二、 向下转型
 *                  发生向上转型 ；父类名称 父类引用 = new 子类实例（）；
 *                  1.通过父类引用.操作的属性和方法，要看父类中是否有这些属性和方法
 *                  2.若存在，判断当前调用的这个方法是否被子类所重写，若重写，则调用子类重写后的方法
 *
 *                  若此时要访问子类中独有的属性和方法，就要发生向下转型
 *
 *                  要想访问Dog类中独有的属性和方法，就要向下转型，将animal引用的Dog类型对象还原为Dog类的引用
 *                  向下转型，将大类型的引用赋值为小类型的引用，需要强转
 *
 *                  向下转型的要求：
 *                  1.要想发生向下转型，必须要先产生向上转型
 *                  2.类型强转存在安全风险，不能将毫无关系的两个类之间进行强转
 *
 *                  使用instanceof 来协助进行向下转型，只有能进行向下转型的引用，instanceof才返回true
 *

 */
public class Demo1 {
    public static void main(String[] args) {
//        Dog dog = new Dog("dog",1);
//        Cat cat = new Cat("cat",2);
//        fun(dog);
//        fun(cat);
        Animal animal = buyAnimal("dog");
        Animal animal1 = buyAnimal("cat");
        Animal animal2 = new Animal("animal",2);
        fun(animal2);
        fun(animal);
        fun(animal1);
        //instanceof 协助进行向下类型转换
        //使用instanceof判断当前引用是否指向Dog类的实例
        if(animal instanceof Dog){
            System.out.println("animal is a dog!");
        }
    }
    public static void fun(Animal animal){
        animal.eat();
    }
    public static Animal buyAnimal(String animalName){
        if(animalName.equals("dog")){
            return new Dog("66",2);
        }else if(animalName.equals("cat")){
            return new Cat("maiomiao",2);
        }else {
            System.out.println("本店没有该动物");
            return null;
        }
    }
}
